#include "fwWindowsOpenGLES.h"
#include "..\Game\fwGameContent.h"

WindowsOpenGLESv2::WindowsOpenGLESv2(FWuint iWidth, FWuint iHeight, char * szTitle, FWuint iFlags)
	:Windows()
{
	LOGIDBG("Init WindowsOpenGLESv2\n");
	m_iWidth = iWidth;
	m_iHeight = iHeight;
	m_szTitle = szTitle;
	m_iFlags = iFlags;

	//MessageService::GetInstance()->RegisterMessage(this, "DRAW", CallBackDraw);
	//MessageService::GetInstance()->RegisterMessage(this, "START_GAME", CallBackStartDevice);
	TagControll::Alloc();
	TagControll::Instance->RegisterTag(this, FW_START_GAME_EVENT, CallBackStartDevice);
	MessageService::GetInstance()->RegisterMessage(this, "END_GAME", CallBackEndDevice);
	MessageService::GetInstance()->RegisterMessage(this, "GET_CURSOR", NULL);
	m_pESContext = new ESContext();
}

WindowsOpenGLESv2::~WindowsOpenGLESv2()
{
	LOGIDBG("Destroy WindowsOpenGLESv2\n");
}

int WindowsOpenGLESv2::Init()
{
	LOGI("Init Windows for run OpenGLESv2.\n");
	return !CreateWindows(); //if CreateWindows return true, it will return 0
}

void WindowsOpenGLESv2::Exit()
{
	PostQuitMessage(WM_QUIT);

	//SendMessage(m_pESContext->_eglHWND, WM_QUIT, 0, 0);
}

void WindowsOpenGLESv2::Destroy()
{
	//SAFE_DEL_ARRAY(m_szTitle);  //Store in stack memory
	SAFE_DEL(m_pESContext);
}

FWboolean WindowsOpenGLESv2::CreateWindows()
{
	EGLint attribList[] =
	{
		EGL_RED_SIZE, 5,
		EGL_GREEN_SIZE, 6,
		EGL_BLUE_SIZE, 5,
		EGL_ALPHA_SIZE, (m_iFlags & ES_WINDOW_ALPHA) ? 8 : EGL_DONT_CARE,
		EGL_DEPTH_SIZE, (m_iFlags & ES_WINDOW_DEPTH) ? 8 : EGL_DONT_CARE,
		EGL_STENCIL_SIZE, (m_iFlags & ES_WINDOW_STENCIL) ? 8 : EGL_DONT_CARE,
		EGL_SAMPLE_BUFFERS, (m_iFlags & ES_WINDOW_MULTISAMPLE) ? 1 : 0,
		EGL_NONE
	};


	if (!CreateClientWindows())
	{
		return false;
	}

	if (!m_pESContext->CreateESContext(attribList))
	{
		return false;
	}

	return EGL_TRUE;
}

FWboolean WindowsOpenGLESv2::CreateClientWindows()
{
	WNDCLASS wndclass = { 0 };
	DWORD    wStyle = 0;
	RECT     windowRect;
	HINSTANCE hInstance = GetModuleHandle(NULL);


	wndclass.style = CS_OWNDC;
	wndclass.lpfnWndProc = (WNDPROC)WinProc;
	wndclass.hInstance = hInstance;
	wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	wndclass.lpszClassName = TEXT("opengles2.0");

	if (!RegisterClass(&wndclass))
		return FALSE;

	wStyle = WS_VISIBLE | WS_POPUP | WS_BORDER | WS_SYSMENU | WS_CAPTION;

	// Adjust the window rectangle so that the client area has
	// the correct number of pixels
	windowRect.left = 0;
	windowRect.top = 0;
	windowRect.right = m_iWidth;
	windowRect.bottom = m_iHeight;

	AdjustWindowRect(&windowRect, wStyle, FALSE);
	m_pESContext->_eglHWND = CreateWindow(
		"opengles2.0",
		m_szTitle,
		wStyle,
		50,
		0,
		windowRect.right - windowRect.left,
		windowRect.bottom - windowRect.top,
		NULL,
		NULL,
		hInstance,
		NULL);

	if (m_pESContext->_eglHWND == NULL)
		return false;

	ShowWindow(m_pESContext->_eglHWND, TRUE);

	return true;
}

void WindowsOpenGLESv2::KeyboardUpdate(WPARAM wParam, FWboolean status)
{

}

void WindowsOpenGLESv2::MouseUpdate()
{

}

void WindowsOpenGLESv2::InternalRun(const FWobject extra)
{
	MSG msg = { 0 };
	int done = 0;
	DWORD lastTime = GetTickCount();

	IGame * game = (IGame*)extra;

	while (!done)
	{
		int gotMsg = (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != 0);
		DWORD curTime = GetTickCount();
		float deltaTime = (float)(curTime - lastTime) / 1000.0f;
		lastTime = curTime;

		if (gotMsg)
		{
			if (msg.message == WM_QUIT)
			{
				done = 1;
				SendMessage(m_pESContext->_eglHWND, WM_CLOSE, 0, NULL);
			}
			else
			{
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		}
		else
		{
			SendMessage(m_pESContext->_eglHWND, WM_PAINT, 0, 0);
		}
		game->Update(deltaTime);
		game->Draw();
		eglSwapBuffers(m_pESContext->_eglDisplay, m_pESContext->_eglSurface);
	}
}